#!/bin/sh

# 时间保持脚本 - 用于断电环境下的系统时间管理
# 功能：上电时恢复时间，运行期间每分钟保存时间到3个文件
# 适用于RK3568+Ubuntu系统

# 配置参数
TIME_DIR="/root/user_data/time_file"
TIME_FILE1="$TIME_DIR/time1.txt"
TIME_FILE2="$TIME_DIR/time2.txt"
TIME_FILE3="$TIME_DIR/time3.txt"
LOG_FILE="$TIME_DIR/time_keeper.log"
MAX_LOG_LINES=10000  # 最大日志行数，可根据需要修改

# 清理日志文件，保持指定行数
cleanup_log_file() {
    if [ -f "$LOG_FILE" ]; then
        local current_lines=$(wc -l < "$LOG_FILE" 2>/dev/null || echo "0")
        if [ "$current_lines" -gt "$MAX_LOG_LINES" ]; then
            # 计算需要保留的行数（从文件末尾开始）
            local lines_to_keep=$MAX_LOG_LINES
            
            # 创建临时文件保存最新的日志条目
            local temp_file="$LOG_FILE.tmp"
            tail -n "$lines_to_keep" "$LOG_FILE" > "$temp_file"
            
            # 替换原文件
            mv "$temp_file" "$LOG_FILE"
            
            # 记录清理操作（不使用log_message避免递归）
            echo "$(date '+%Y-%m-%d %H:%M:%S') - 日志文件已清理，从 $current_lines 行减少到 $lines_to_keep 行" >> "$LOG_FILE"
        fi
    fi
}

# 日志函数
log_message() {
    # 确保日志目录存在
    if [ ! -d "$TIME_DIR" ]; then
        mkdir -p "$TIME_DIR"
    fi
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
}

# 确保目录存在
ensure_directory() {
    if [ ! -d "$TIME_DIR" ]; then
        mkdir -p "$TIME_DIR"
        log_message "创建时间存储目录: $TIME_DIR"
    fi
}

# 安全写入文件并确保同步到存储器
safe_write_time() {
    local file="$1"
    local timestamp="$2"
    
    # 写入时间戳
    echo "$timestamp" > "$file"
    
    # 强制同步到存储器
    sync
    
    # 额外确保该文件同步
    if command -v fsync >/dev/null 2>&1; then
        fsync "$file" 2>/dev/null || true
    fi
    
    log_message "时间已写入并同步: $file ($timestamp)"
}

# 读取单个时间文件
read_time_file() {
    local file="$1"
    if [ -f "$file" ] && [ -s "$file" ]; then
        cat "$file" 2>/dev/null | head -n1
    else
        echo ""
    fi
}

# 验证时间戳格式是否有效
is_valid_timestamp() {
    local timestamp="$1"
    # 检查是否为10位数字（Unix时间戳）
    if echo "$timestamp" | grep -E '^[0-9]{10}$' >/dev/null; then
        # 检查时间戳是否在合理范围内（2020年到2040年）
        if [ "$timestamp" -ge 1577836800 ] && [ "$timestamp" -le 2208988800 ]; then
            return 0
        fi
    fi
    return 1
}

# 3取2策略获取可靠时间
get_reliable_time() {
    local time1=$(read_time_file "$TIME_FILE1")
    local time2=$(read_time_file "$TIME_FILE2")
    local time3=$(read_time_file "$TIME_FILE3")
    
    log_message "读取到的时间: file1=$time1, file2=$time2, file3=$time3"
    
    # 验证时间戳有效性
    local valid1=0; is_valid_timestamp "$time1" && valid1=1
    local valid2=0; is_valid_timestamp "$time2" && valid2=1
    local valid3=0; is_valid_timestamp "$time3" && valid3=1
    
    # 3取2策略：至少两个相同的有效时间戳
    if [ $valid1 -eq 1 ] && [ $valid2 -eq 1 ] && [ "$time1" = "$time2" ]; then
        echo "$time1"
        return 0
    elif [ $valid1 -eq 1 ] && [ $valid3 -eq 1 ] && [ "$time1" = "$time3" ]; then
        echo "$time1"
        return 0
    elif [ $valid2 -eq 1 ] && [ $valid3 -eq 1 ] && [ "$time2" = "$time3" ]; then
        echo "$time2"
        return 0
    fi
    
    # 如果没有两个相同的，选择最新的有效时间戳
    local latest_time=""
    local latest_timestamp=0
    
    if [ $valid1 -eq 1 ] && [ "$time1" -gt "$latest_timestamp" ]; then
        latest_time="$time1"
        latest_timestamp="$time1"
    fi
    if [ $valid2 -eq 1 ] && [ "$time2" -gt "$latest_timestamp" ]; then
        latest_time="$time2"
        latest_timestamp="$time2"
    fi
    if [ $valid3 -eq 1 ] && [ "$time3" -gt "$latest_timestamp" ]; then
        latest_time="$time3"
        latest_timestamp="$time3"
    fi
    
    if [ -n "$latest_time" ]; then
        log_message "使用最新的有效时间戳: $latest_time"
        echo "$latest_time"
        return 0
    fi
    
    log_message "未找到有效的时间戳"
    return 1
}

# 设置系统时间
set_system_time() {
    local timestamp="$1"
    if is_valid_timestamp "$timestamp"; then
        date -s "@$timestamp" >/dev/null 2>&1
        if [ $? -eq 0 ]; then
            log_message "系统时间已设置为: $(date -d "@$timestamp" '+%Y-%m-%d %H:%M:%S')"
            return 0
        else
            log_message "设置系统时间失败"
            return 1
        fi
    else
        log_message "无效的时间戳: $timestamp"
        return 1
    fi
}

# 保存当前时间到3个文件
save_current_time() {
    local current_timestamp=$(date +%s)
    
    # 依次写入3个文件，每次写入后都同步到存储器
    safe_write_time "$TIME_FILE1" "$current_timestamp"
    safe_write_time "$TIME_FILE2" "$current_timestamp"
    safe_write_time "$TIME_FILE3" "$current_timestamp"
    
    log_message "当前时间已保存到3个文件: $(date '+%Y-%m-%d %H:%M:%S')"
}

# 初始化时间恢复
initialize_time() {
    log_message "开始初始化时间恢复..."
    
    # 确保目录存在
    ensure_directory
    
    # 尝试从文件恢复时间
    reliable_time=$(get_reliable_time)
    
    if [ -n "$reliable_time" ]; then
        # 恢复时间
        set_system_time "$reliable_time"
        log_message "时间恢复完成"
    else
        # 没有可用的时间记录，使用当前系统时间初始化
        log_message "未找到有效的时间记录，使用当前系统时间初始化"
        save_current_time
    fi
}

# 主循环 - 每分钟保存时间
time_keeper_loop() {
    log_message "开始时间保持循环..."
    
    while true; do
        sleep 60  # 等待1分钟
        save_current_time
    done
}

# 信号处理 - 优雅退出
cleanup() {
    log_message "收到退出信号，保存最后一次时间..."
    save_current_time
    log_message "时间保持脚本退出"
    exit 0
}

# 设置信号处理
trap cleanup TERM INT

# 主程序入口
main() {
    # 首先清理日志文件（在记录任何日志之前）
    cleanup_log_file
    
    log_message "时间保持脚本启动"
    
    # 初始化时间恢复
    initialize_time
    
    # 启动时间保持循环
    time_keeper_loop
}

# 检查是否以root权限运行
if [ "$(id -u)" -ne 0 ]; then
    echo "错误: 此脚本需要root权限运行"
    exit 1
fi

# 启动主程序
main 